package com.yanqu.road.server.manager.tomb;

import com.yanqu.road.logic.activity.tomb.config.TombConfig;
import com.yanqu.road.logic.activity.tomb.config.entity.ActivityTombRepair;
import com.yanqu.road.pb.tomb.Tomb;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.tomb.entity.DbTombPosition;
import com.yanqu.road.server.manager.tomb.entity.DbTombUser;
import com.yanqu.road.server.manager.tomb.entity.UserNiantuRank;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TombActivityUnion {
    private int activityId;
    private TombActivity activity;

    private String unionUid;

    public static TombActivityUnion newInstance(TombActivity activity, String unionUid) {
        TombActivityUnion tombMazeUnion = new TombActivityUnion();
        tombMazeUnion.activityId = activity.getActivityInfo().getActivityId();
        tombMazeUnion.activity = activity;
        tombMazeUnion.unionUid = unionUid;
        for (ActivityTombRepair repair : activity.getTombRepairConfig()) {       //初始化商会修补(秦俑再世)
            tombMazeUnion.tombRepairProgress.put(repair.getId(), 0L);
        }
        return tombMazeUnion;
    }

    private final Map<Long, DbTombUser> allDbTombUserMap = new ConcurrentHashMap<>();


    private final Map<Integer, Map<String, DbTombPosition>> dbTombPositionMapMap = new ConcurrentHashMap<>();

    private final Map<Integer, Long> tombRepairProgress = new ConcurrentHashMap<>();

    private final List<UserNiantuRank> repairRankList = new ArrayList<>();


    public void addDbTombUser(DbTombUser dbTombUser) {
        this.allDbTombUserMap.put(dbTombUser.getUserId(), dbTombUser);
    }



    public Map<Integer, Long> getTombRepairProgress() {
        return tombRepairProgress;
    }


    public void addDbTombPosition(DbTombPosition dbTombPosition) {
        if (!this.dbTombPositionMapMap.containsKey(dbTombPosition.getFloor())) {
            this.dbTombPositionMapMap.put(dbTombPosition.getFloor(), new ConcurrentHashMap<>());
        }
        this.dbTombPositionMapMap.get(dbTombPosition.getFloor()).put(dbTombPosition.getKey(), dbTombPosition);
    }

    public Map<String, DbTombPosition> getDbTombPositionMap(int floor) {
        Map<String, DbTombPosition> dbTombPositionMap = this.dbTombPositionMapMap.get(floor);
        if (dbTombPositionMap == null) {
            this.dbTombPositionMapMap.put(floor, new ConcurrentHashMap<>());
        }
        return this.dbTombPositionMapMap.get(floor);
    }




    public Tomb.TombRepairRankResp.Builder getNiantuRank(long userId) {
        DbTombUser dbTombUser = this.activity.getDbData().getDbTombUser(userId);
        if (dbTombUser != null) {
            updateNiantuRank(dbTombUser);
        }

        Tomb.TombRepairRankResp.Builder builder = Tomb.TombRepairRankResp.newBuilder();
        synchronized (repairRankList) {
            int i = 1;
            for (UserNiantuRank userNiantuRank : repairRankList) {
                if (userNiantuRank.getUseItemNum() == 0) {
                    continue;
                }
                Tomb.TombRepairRankInfo.Builder rankBuilder = Tomb.TombRepairRankInfo.newBuilder();
                rankBuilder.setRank(i);
                rankBuilder.setId(userNiantuRank.getUserId());
                rankBuilder.setName(userNiantuRank.getName());
                rankBuilder.setServerId(userNiantuRank.getServerId());
                rankBuilder.setValue(userNiantuRank.getUseItemNum());
                builder.addTombRepairRankInfoList(rankBuilder);
                i++;
            }
        }

        return builder;
    }

    public void updateNiantuRank(DbTombUser dbTombUser) {
        synchronized (repairRankList) {
            if (getNiantuUserRank(dbTombUser.userId) == null) {
                UserNiantuRank userNiantuRank = new UserNiantuRank(dbTombUser.userId, dbTombUser.getUserInfo().getNickName(), dbTombUser.getUserNianTuNum(), dbTombUser.getUserInfo().getServerId());
                repairRankList.add(userNiantuRank);
            }
            getNiantuUserRank(dbTombUser.userId).setUseItemNum(dbTombUser.getUserNianTuNum());
            repairRankList.sort((o1, o2) -> {
                if (o2.getUseItemNum() > o1.getUseItemNum()) {
                    return 1;
                } else if (o2.getUseItemNum() < o1.getUseItemNum()) {
                    return -1;
                } else {
                    return 0;
                }
            });
        }
    }

    private UserNiantuRank getNiantuUserRank(long userId) {
        for (UserNiantuRank userNiantuRank : repairRankList) {
            if (userNiantuRank.getUserId() == userId) {
                return userNiantuRank;
            }
        }
        return null;
    }

    /**
     * 秦俑再现黏土修复
     */
    public Tomb.TombRepairResp.Builder tombRepair(long userId, long useItemNum) {
        if (!allDbTombUserMap.containsKey(userId)) {
            synchronized (allDbTombUserMap) {
                if (!allDbTombUserMap.containsKey(userId)) {
                    addDbTombUser(activity.getDbData().getDbTombUser(userId));
                }
            }
        }
        TombConfig config = activity.getConfig();
        ActivityTombRepair[] repairConfigList = config.getRepairs();
        boolean allFinish = true;
        Tomb.TombRepairResp.Builder builder = Tomb.TombRepairResp.newBuilder();
        DbTombUser dbTombUser = activity.getDbData().getDbTombUser(userId);
        if (dbTombUser == null) {
            builder.setRealUseNum(0);
            builder.setRet(GameErrorCode.E_TOMB_USER_NOT_FOUND);
            return builder;
        }


        long totalProcess = getUnionTotalProgress();  //总进度
        for (ActivityTombRepair repairConfig : repairConfigList) {
            if (totalProcess < repairConfig.getSchedule()) {        //如果还有没完成区域
                allFinish = false;
                long finishPlaceNeedItem = 0;        //完成该区域需要的黏土数量
                if ((repairConfig.getSchedule() - totalProcess) % config.getRepairItemProgress() == 0) {
                    finishPlaceNeedItem = (repairConfig.getSchedule() - totalProcess) / config.getRepairItemProgress();
                } else {
                    finishPlaceNeedItem = (repairConfig.getSchedule() - totalProcess) / config.getRepairItemProgress() + 1;
                }
                if (useItemNum == 1) {     //单个使用
                    if (finishPlaceNeedItem == 1) {
                        builder.setFinish(1);
                    }

                    builder.setRet(0);
                    builder.setId(repairConfig.getId());
                    builder.setRealUseNum(1);
                } else {            //一键使用
                    long realUseNum = 0;
                    if (finishPlaceNeedItem > useItemNum) {    //如果需求大于可以使用的道具
                        realUseNum = useItemNum;
                        builder.setFinish(0);
                    } else {
                        realUseNum = finishPlaceNeedItem;
                        builder.setFinish(1);
                    }
                    builder.setRet(0);
                    builder.setId(repairConfig.getId());
                    builder.setRealUseNum(realUseNum);
                }
                break;

            }

        }

        UserNiantuRank niantuUserRank = getNiantuUserRank(userId);
        if (niantuUserRank == null) {
            synchronized (repairRankList) {
                niantuUserRank = getNiantuUserRank(userId);
                if (niantuUserRank == null) {
                    niantuUserRank = new UserNiantuRank();
                    niantuUserRank.setName(dbTombUser.getUserInfo().getNickName());
                    niantuUserRank.setUseItemNum(0);
                    niantuUserRank.setServerId(dbTombUser.getUserInfo().getServerId());
                    niantuUserRank.setUserId(userId);
                    repairRankList.add(niantuUserRank);
                }
            }
        }

        if (allFinish) {         //全部完成了
            synchronized (dbTombUser.getPvpUnionChooseMap()) {
                dbTombUser.setUserNianTuNum(dbTombUser.getUserNianTuNum() + useItemNum);
                dbTombUser.refreshUpdateTime();
            }
            niantuUserRank.setUseItemNum(niantuUserRank.getUseItemNum() + useItemNum);
            updateNiantuRank(dbTombUser);
            updateProgressMap(getUnionTotalProgress());
            broadcastUnionRepairProgress();
            builder.setFinish(1);
            builder.setRet(0);
            builder.setId(0);
            builder.setRealUseNum(useItemNum);
            builder.addAllRepairData(getProgressProto());       //加入当前进度
            return builder;
        }

        //本次增加了进度
        niantuUserRank.setUseItemNum(niantuUserRank.getUseItemNum() + builder.getRealUseNum());
        synchronized (dbTombUser.getPvpUnionChooseMap()) {
            dbTombUser.setUserNianTuNum(dbTombUser.getUserNianTuNum() + builder.getRealUseNum());
            dbTombUser.refreshUpdateTime();
        }
        updateNiantuRank(dbTombUser);       //更新商会内黏土使用rank
        updateProgressMap(getUnionTotalProgress()); //更新商会黏土修复进度表
        broadcastUnionRepairProgress();             //同步进度消息给所有成员
        builder.addAllRepairData(getProgressProto());       //回复消息中加入当前进度
        return builder;
    }

    /**
     * 更新秦俑再现商会进度map
     */
    public void updateProgressMap(long totalProgress) {
        ActivityTombRepair[] repairConfigList = activity.getConfig().getRepairs();
        long levelProcess = 0; //前一层进度上限
        for (int i = 0; i < repairConfigList.length; i++) {
            if (totalProgress < repairConfigList[i].getSchedule()) {//商会总进度小于配置内当前层数进度 当前层数进度未完成
                tombRepairProgress.put(repairConfigList[i].getId(), (totalProgress - levelProcess));
                break;
            } else {                 //进度完成
                tombRepairProgress.put(repairConfigList[i].getId(), repairConfigList[i].getSchedule() - levelProcess);//设置当前层数进度
                levelProcess = repairConfigList[i].getSchedule();   //设置前层进度上限
            }
        }
        return;
    }

    /**
     * 通过每个玩家使用的道具计算总进度
     */
    public long getUnionTotalProgress() {
        long totalProgress = 0;
        long totalItemNum = 0;
        for (DbTombUser dbTombUser : allDbTombUserMap.values()) {
            totalItemNum += dbTombUser.getUserNianTuNum();
        }
        totalProgress = totalItemNum * activity.getConfig().getRepairItemProgress();
        return totalProgress;
    }

    public List<Tomb.TombRepairProgress> getProgressProto() {
        List<Tomb.TombRepairProgress> progressList = new ArrayList<>();
        for (Map.Entry<Integer, Long> entry : tombRepairProgress.entrySet()) {
            Tomb.TombRepairProgress.Builder builder = Tomb.TombRepairProgress.newBuilder();
            builder.setId(entry.getKey());
            builder.setProgress(entry.getValue());
            progressList.add(builder.build());
        }
        return progressList;
    }

    /**
     * 发送商会进度到服务器 让他们处理自己服务器的玩家成就
     */
    public void broadcastUnionRepairProgress() {
        List<Long> serverIdList = this.activity.getActivityInfo().getServerIdList();
        if (!serverIdList.isEmpty()) {
            for (long serverId : serverIdList) {
                Tomb.TombUpdateUserRepairCondition.Builder builder = Tomb.TombUpdateUserRepairCondition.newBuilder();
                //从参与用户中寻找这个服务器的玩家
                for (DbTombUser dbTombUser : allDbTombUserMap.values()) {
                    if (dbTombUser.getUserInfo().getServerId() == serverId) {
                        builder.addUserId(dbTombUser.getUserId());
                    }
                }
                //加入当前商会进度
                builder.addAllRepairData(getProgressProto());
                //发消息
                MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(Protocol.S_TOMB_UPDATE_REPAIR_CONDITION, builder));
            }
        }
    }

    public String getUnionUid() {
        return unionUid;
    }

    public Map<Long, DbTombUser> getAllDbTombUserMap() {
        return allDbTombUserMap;
    }

    public List<DbTombUser> getAllDbTombUser() {
        return new ArrayList<>(this.allDbTombUserMap.values());
    }



    public long getTotalActiveUserAbility() {
        long total = 0;
        List<DbTombUser> allDbTombUser = this.getAllDbTombUser();
        for (DbTombUser dbTombUser : allDbTombUser) {
            if (dbTombUser.getCostEnergy() == 0) {
                continue;
            }
            total = total + dbTombUser.getTotalAttack();
        }
        return total;
    }

    public Map<Integer, Map<String, DbTombPosition>> getDbTombPositionMapMap() {
        return dbTombPositionMapMap;
    }
}
